package edu.lambdateacher.parser;

/*
 LambdaTeacher
 Copyright (C) 2000  Kim Mason
 Copyright (C) 2014  Vitalij Zadneprovskij

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

import java.io.Reader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

/**
 * The Scanner class for the Lambda Calculus. It takes in a string, and converts
 * that into a Vector of tokens.
 */
public class LambdaScanner implements Iterator<LambdaToken>{

	private final static Logger LOGGER = Logger.getLogger(LambdaScanner.class);

	private List<LambdaToken> tokenlist; // the list of tokens
	private int currenttoken = 0; // the token which we're up to

	/**
	 * A Constructor. Takes in a string, and tokenises it into tokenlist. Note
	 * that the tokenlist in LambdaScanner contains an eof token. The
	 * StreamTokeniser class is used to tokenise the input stream.
	 */
	public LambdaScanner(Reader inread) {
		StreamTokeniser strtok = new StreamTokeniser();

		// if there isn't an input stream, just create
		// an empty token vector
		if (inread != null) {
			tokenlist = strtok.tokeniseStream(inread);
		} else {
			tokenlist = new ArrayList<LambdaToken>();
		}
		((ArrayList)tokenlist).trimToSize();
		strtok = null;
	}

	/**
	 * Returns the current token
	 */
	public synchronized LambdaToken currentToken() {
		// if we are in the tokenlist, return the current token
		if (currenttoken < tokenlist.size()) {
			return (LambdaToken) tokenlist.get(currenttoken);
		} else
		// return end of file
		{
			return new LambdaToken(LambdaTokenType.EOF);
		}
	}

	/**
	 * Moves on to the next token and returns it
	 */
	public synchronized LambdaToken next() {
		// If we aren't at the end of the tokens, move on to the next one,
		// otherwise
		// return EOF
		if (currenttoken < tokenlist.size() - 1) {
			currenttoken = currenttoken + 1;
			return (LambdaToken) tokenlist.get(currenttoken);
		} else {
			// we might be on the last element, so move forward one
			if (currenttoken < tokenlist.size()) {
				currenttoken = currenttoken + 1;
			}
			LambdaToken thetoken = new LambdaToken(LambdaTokenType.EOF);
			return thetoken;
		}
	}
	
	public boolean hasNext(){
		if(currenttoken < tokenlist.size()){
			return true;
		}else{
			return false;
		}
	}
	
	public void remove(){
		
	}

	@Override
	public String toString() {
		return "LambdaScanner [tokenlist=" + tokenlist + ", currenttoken=" + currenttoken + "]";
	}

}
